package com.copa.module.user.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.copa.domain.PageVo;
import com.copa.domain.ResponseDto;

import com.copa.module.user.domain.entity.CustomerUserEntity;
import com.copa.module.user.domain.entity.UserEntity;
import com.copa.module.user.domain.vo.WechatUserVo;
import com.copa.module.user.manage.UserRoleManage;
import com.copa.module.user.mapper.UserDao;
import com.copa.module.user.service.UserService;
import com.copa.utils.JwtTokenUtils;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * @author copa
 * @createDate 2021-01-05 8:35
 * @function
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleManage userRoleManage;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtils jwtTokenUtils;


    @Override
    public ResponseDto<IPage<UserEntity>> list(PageVo pageVO) {
        IPage<UserEntity> userEntities = userDao.selectPage(new Page<>(pageVO.getCurrent(), pageVO.getSize()), null);
        if (ObjectUtil.isNotNull(userEntities)) {
            return ResponseDto.success(userEntities);
        }
        return ResponseDto.errorMsg("抱歉，没查到该用户信息！");
    }

    @Override
    public ResponseDto<UserEntity> findByUsername(String username) {
        UserEntity userEntity = userDao.findByUsername(username);
        if (ObjectUtil.isNotNull(userEntity)) {
            return ResponseDto.success(userEntity);
        }
        return ResponseDto.errorMsg("抱歉，没查到该用户信息！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto<String> login(String code, WechatUserVo wechatUserVo) {
        // 微信接口拿open_id
        ResponseDto<String> codeRsg = userRoleManage.getOpenId(code);
        if (codeRsg.isNotSuccess()) {
            return ResponseDto.errorMsg(codeRsg.getMsg());
        }
        String openId = codeRsg.getData();
        UserEntity user = findUserByOpenId(openId);
        if (ObjectUtil.isNull(user)) {
            // 添加用户
            ResponseDto<UserEntity> insertUserRes = insertUser(openId, wechatUserVo);
            if (insertUserRes.isNotSuccess()) {
                return ResponseDto.errorMsg(insertUserRes.getMsg());
            }
            user = insertUserRes.getData();
        }

        // 通过用户名和密码创建一个 Authentication 认证对象，实现类为 UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), "123456");

        try {
            //通过 AuthenticationManager（默认实现为ProviderManager）的authenticate方法验证 Authentication 对象
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            CustomerUserEntity principal = (CustomerUserEntity) authentication.getPrincipal();
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(principal.getUser(), null, authentication.getAuthorities());

            //将 Authentication 绑定到 SecurityContext
            SecurityContextHolder.getContext().setAuthentication(authentication);
            //生成Token
            String token = jwtTokenUtils.createToken(authentication);

//            ResponseDto<UserLoginDto> resMsg = userRoleManage.findUserByUsernameAndPassword(principal.getUser().getId());
//            if (resMsg.isNotSuccess()) {
//                return resMsg;
//            }
//            UserLoginDto userLoginDTO = new UserLoginDto();
//            userLoginDTO.setToken("Bearer " + token);
            return ResponseDto.success("Bearer " + token);

        } catch (BadCredentialsException authentication) {
            return ResponseDto.errorCodeMsg(401,"Login failed");
        }
    }

    private ResponseDto<UserEntity> insertUser(String openId, WechatUserVo wechatUserVo) {
        UserEntity user = new UserEntity();
        user.setAvatarUrl(wechatUserVo.getAvatarUrl())
                .setGender(wechatUserVo.getGender())
                .setUsername(wechatUserVo.getNickName())
                .setIsDelete(0)
                .setIsEnabled(1)
                .setPassword("$2a$10$rQ6qne1.xKPWE0Yjm0tMbOEXdmj4Vd/tJi0t3nwxI5AJGlCMq.oXu")
                .setOpenId(openId);
        userDao.insert(user);
        user = findUserByOpenId(user.getOpenId());
        ResponseDto<String> addUserRoleRes = userRoleManage.addUserRole(user);
        if (addUserRoleRes.isNotSuccess()) {
            return ResponseDto.errorMsg(addUserRoleRes.getMsg());
        }
        return ResponseDto.success(user);
    }

    private UserEntity findUserByOpenId(String openId) {
        Map<String, Object> selectCondition = Maps.newHashMap();
        selectCondition.put("open_id", openId);
        List<UserEntity> userEntities = userDao.selectByMap(selectCondition);
        if (ObjectUtil.isNotEmpty(userEntities)
                && ObjectUtil.length(userEntities) > 0) {
            return userEntities.get(0);
        }
        return null;

    }
}
